Fix removeUnused mode not loading plugin checks and alt names#278
Fix removeUnused mode not loading plugin checks and alt names#278kelvinou01 wants to merge 1 commit into
Conversation
Generate changelog in
|
082b6c1 to
e507d60
Compare
✅ Successfully generated changelog entry!Need to regenerate?Simply interact with the changelog bot comment again to regenerate these entries. 📋Changelog Preview🐛 Fixes
|
| '''.stripIndent(true) | ||
|
|
||
| when: | ||
| runTasksSuccessfully('compileAllErrorProne', '-PerrorProneRemoveUnused=ArrayToString') |
There was a problem hiding this comment.
RemoveUnused doesn't take arguments — this argument was being ignored
| @BugPattern( | ||
| severity = BugPattern.SeverityLevel.ERROR, | ||
| summary = "This check is meant only for testing suppressible-error-prone functionality") | ||
| public final class ShouldNotReturn extends BugChecker implements MethodTreeMatcher { |
There was a problem hiding this comment.
Did you use this anywhere?
| ServiceLoader.load(BugChecker.class).stream().map(ServiceLoader.Provider::get); | ||
| Stream<String> pluginCheckNames = | ||
| StreamEx.of(pluginChecks).flatMap(bugchecker -> bugchecker.allNames().stream()); | ||
| private static Supplier<Map<String, Set<String>>> canonicalToAllNames = VisitorState.memoize(state -> { |
There was a problem hiding this comment.
| private static Supplier<Map<String, Set<String>>> canonicalToAllNames = VisitorState.memoize(state -> { | |
| private static final Supplier<Map<String, Set<String>>> canonicalToAllNames = VisitorState.memoize(state -> { |
|
|
||
| public static Set<String> allBugcheckerNames() { | ||
| return cachedAllBugcheckerNames.get(); | ||
| private static Supplier<Set<String>> allNames = |
There was a problem hiding this comment.
| private static Supplier<Set<String>> allNames = | |
| private static final Supplier<Set<String>> allNames = |
| .flatMap(entry -> entry.getValue().stream()) | ||
| .collect(Collectors.toSet())); | ||
|
|
||
| private static Supplier<Map<String, Set<String>>> nameToPossibleCanonicalNames = |
There was a problem hiding this comment.
| private static Supplier<Map<String, Set<String>>> nameToPossibleCanonicalNames = | |
| private static final Supplier<Map<String, Set<String>>> nameToPossibleCanonicalNames = |
| .flatMap(entry -> entry.getValue().stream()) | ||
| .collect(Collectors.toSet())); | ||
|
|
||
| private static Supplier<Map<String, Set<String>>> nameToPossibleCanonicalNames = |
There was a problem hiding this comment.
Is it possible to have multiple checks share the same alt name? I imagine so, though it's also pretty surprising
| declaration, state, suppression -> !AllErrorprones.allBugcheckerNames(state) | ||
| .contains(suppression)); |
There was a problem hiding this comment.
You were previously removing the for-rollout prefix and aren't doing so anymore. Is that intentional?
| String existingSuppression = AnnotationUtils.annotationStringValues( | ||
| SuppressWarningsUtils.getSuppressWarnings(declaration) | ||
| .get()) | ||
| .filter(suppression -> allNames.contains(SuppressWarningsUtils.stripForRollout(suppression))) | ||
| .collect(MoreCollectors.first()) | ||
| .get(); | ||
| FIXES.getExisting(declaration).addSuppression(existingSuppression); |
There was a problem hiding this comment.
Shouldn't you keep all the ones that might already exist, rather than just the first one? (especially the non-rollout ones)
| String existingSuppression = AnnotationUtils.annotationStringValues( | ||
| SuppressWarningsUtils.getSuppressWarnings(declaration) | ||
| .get()) | ||
| .filter(suppression -> allNames.contains(SuppressWarningsUtils.stripForRollout(suppression))) | ||
| .collect(MoreCollectors.first()) | ||
| .get(); |
There was a problem hiding this comment.
Could this leverage suppressionsOn in some way?
| .map(Provider::get) | ||
| .collect(Collectors.toList()); | ||
| EntryStream<String, Set<String>> pluginCheckNames = | ||
| StreamEx.of(pluginChecks).mapToEntry(BugChecker::canonicalName, BugChecker::allNames); |
There was a problem hiding this comment.
BugChecker#allNames will return for-rollout:Name if we've patched the errorprone classes in the artifact transform.
There was a problem hiding this comment.
Which may be what we want...
| // Use the same classloader that Error Prone was loaded from to avoid classloader skew | ||
| // when using Error Prone plugins together with the Error Prone javac plugin. | ||
| JavacProcessingEnvironment processingEnvironment = JavacProcessingEnvironment.instance(state.context); | ||
| ClassLoader loader = processingEnvironment.getProcessorClassLoader(); |
There was a problem hiding this comment.
I wonder if there's any real difference between this and state.getClass().getClassLoader()? The latter does not require interacting with so many compiler APIs or module imports.
Before this PR
A few bugs in suppressible-error-prone:
After this PR
==COMMIT_MSG==
Fix removeUnused mode not loading plugin checks and alt names
==COMMIT_MSG==
Possible downsides?
Probably next PR: RemoveUnused should not remove human-made suppressions. For example, a human-made suppression on SafeLoggingPropagation for a method which is safe to log. RemoveUnused + Apply should not remove the suppression and add the
@Unsafeannotation.If needed, human-authored suppressions can be removed on an allow-list basis. But the correct and performant removal of robot-added suppressions should be the focus here.